home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 280_01 / find0.c < prev    next >
Text File  |  1989-01-11  |  4KB  |  205 lines

  1. /*[FIND0.c of JUGPDS Vol.46]*/
  2. /*
  3. *****************************************************************
  4. *                                *
  5. *    Written by  Hakuo Katayose (JUG-CP/M No.179)        *
  6. *            49-114 Kawauchi-Sanjuunin-machi        *
  7. *            Sendai, Miyagi 980                          *
  8. *            Phone: 0222-61-3219                *
  9. *                                *
  10. *       Modifird by Toshiya Oota   (JUG-CPM No.10)              *
  11. *                   Sakae ko-po 205                 *
  12. *            5-19-6 Hosoda                *
  13. *            Katusikaku Tokyo 124            *
  14. *                                *
  15. *        for MS-DOS Lattice C V3.1J & 80186/V20/V30    *
  16. *                                *
  17. *    Compiler Option: -ccu -k0(1) -ms -n -v -w        *
  18. *                                *
  19. *    Edited & tested by Y. Monma (JUG-CP/M Disk Editor)    *
  20. *            &  T. Ota   (JUG-CP/M Sub Disk Editor)    *
  21. *                                *
  22. *****************************************************************
  23. */
  24.  
  25. /* find - find patterns in text */
  26.  
  27. #include "stdio.h"
  28. #include "dos.h"
  29. #include "tools.h"
  30. #include "toolfunc.h"
  31.  
  32. void main(argc, argv)
  33. int    argc;
  34. char    **argv;
  35.  
  36. {
  37. char    lin[MAXLINE], pat[MAXPAT];
  38. char    opt_l,opt_id, *ap, *cp;
  39. int    i, lno, nl, nx;
  40.  
  41.     if (argc < 2) {
  42.     error("FND991 Usage: find0 [-l][-i] pattern <infile >outfile\n");
  43.     exit();
  44.     }
  45.     opt_l = OFF;
  46.     opt_id= OFF;
  47.  
  48.     nl = 1; i = 0;
  49.     i = 0;
  50.     while (--argc > 0) {
  51.     if ((*++argv)[0] == '-')
  52.         for (ap = argv[0]+1; *ap != '\0'; ap++) {
  53.         if (tolower(*ap) == 'l') {
  54.             opt_l = ON;
  55.             nl = 0;
  56.             for(; isdigit(nx = *(ap+1)); ap++)
  57.             nl = nl*10 + nx - '0';
  58.             nl = (nl == 0 ? 1 : nl);
  59.         }
  60.         else if (tolower(*ap) == 'i')
  61.             opt_id = ON;
  62.         else
  63.             fprintf(STDERR,
  64.             "FND901 [-%c]:Illigal option\n",tolower(*ap));
  65.         }
  66.     cp = *argv;
  67.     }
  68.     if (getpat(cp, pat) == ERROR)
  69.     exit(fprintf(STDERR, "FND903 Illegal pattarn.\n"));
  70.     lno = 0;
  71.     while (getlin(lin, MAXLINE) > 0) {
  72.     lno += nl;
  73.     if (match(lin, pat) == YES)
  74.         if (opt_l == ON) {
  75.         if (opt_id == ON)
  76.             printf("FND101 %6d: %s", lno, lin);
  77.         else
  78.             printf("%6d: %s", lno, lin);
  79.         }
  80.         else {
  81.         if (opt_id == ON)
  82.             printf("FND103 %s", lin);
  83.         else
  84.             printf("%s", lin);
  85.         }
  86.     }
  87. }
  88.  
  89. /* match - find match anywhere on line */
  90. match(lin, pat)
  91. char    lin[], *pat;
  92. {
  93. int i;
  94.  
  95.  
  96.     for (i = 0; lin[i] != '\0'; i++)
  97.     if (amatch(lin, i, pat) >= 0)
  98.     return (YES);
  99.     return(NO);
  100. }
  101.  
  102. /* amatch (non-recursive) - look for stating at lin(from) */
  103. amatch(lin, from, pat)
  104. char    lin[], pat[];
  105. int    from;
  106.  
  107. {
  108. int    i, j, offset, stack;
  109.  
  110.     stack = 0;
  111.     offset = from;
  112.     for (j = 0; pat[j] != '\0'; j += patsiz(pat, j))
  113.     if (pat[j] == CLOSURE) {
  114.         stack = j;
  115.         j += CLOSIZE;
  116.         for (i = offset; lin[i] != '\0'; )
  117.         if (omatch(lin, &i, pat, j) == NO)
  118.             break;
  119.         pat[stack + COUNT] = i - offset;
  120.         pat[stack + START] = offset;
  121.         offset = i;
  122.     }
  123.     else if (omatch(lin, &offset, pat, j) == NO) {
  124.         for (; stack > 0; stack = pat[stack + PREVCL]) {
  125.         if (pat[stack + COUNT] > 0)
  126.             break;
  127.     }
  128.     if (stack <= 0)
  129.         return(-1);
  130.     pat[stack + COUNT]--;
  131.     j = stack + CLOSIZE;
  132.     offset = pat[stack + START] + pat[stack + COUNT];
  133.     }
  134.     return(offset);
  135. }
  136.  
  137. /* patsiz - returns size of pattern entry at pat(n) */
  138. int patsiz(pat, n)
  139. char    pat[];
  140. int    n;
  141.  
  142. {
  143.     switch (pat[n]) {
  144.     case BPAT :
  145.     case EPAT :
  146.     case CHAR :
  147.           return(2);
  148.     case BOL :
  149.     case EOL :
  150.     case ANY :
  151.           return(1);
  152.     case CCL :
  153.     case NCCL:
  154.           return (pat[n+1] + 2);
  155.     case CLOSURE :
  156.           return CLOSIZE;
  157.     default  :
  158.           exit(fprintf(STDERR, "FND911 Error in patsiz: can't happen.\n"));
  159.     }
  160. }
  161.  
  162. /* omatch - try to match a single pattern at pat(j) */
  163. int  omatch(lin, i, pat, j)
  164. char    lin[], pat[];
  165. int    *i, j;
  166.  
  167. {
  168. int    bump;
  169. char    c;
  170.  
  171.     c = lin[ *i ];
  172.     if (c == '\0')
  173.     return(NO);
  174.     bump = -1;
  175.     switch (pat[j]) {
  176.     case BPAT :
  177.     case EPAT : return(YES);
  178.     case CHAR : if (c == pat[j+1])
  179.             bump= 1;
  180.             break;
  181.     case BOL :  if (*i == 0)
  182.             bump = 0;
  183.             break;
  184.     case ANY :  if (c != '\n')
  185.             bump = 1;
  186.             break;
  187.     case EOL :  if (c == '\n')
  188.             bump = 0;
  189.             break;
  190.     case CCL :  if (locate(c, pat, j+1) == YES)
  191.             bump = 1;
  192.             break;
  193.     case NCCL:  if (c != '\n' && locate(c, pat, j+1) == NO)
  194.             bump = 1;
  195.             break;
  196.     default  :  fprintf(STDERR, "FND913 Error in omatch: can't happen.\n");
  197.     }
  198.     if (bump >= 0) {
  199.     *i += bump;
  200.     return(YES);
  201.     }
  202.     return(NO);
  203. }
  204.  
  205.